package com.jeesite.modules.dataScreen.service;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
public class HotConcernTimer {

    Map<String, Long> cacheMap = new HashMap<>();

    private ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();

    public HotConcernTimer() {
        taskScheduler.setPoolSize(20);
        taskScheduler.setThreadNamePrefix("timer-");
        taskScheduler.initialize();

    }


    private ScheduledFuture<?> schedule;

    private AtomicLong result = new AtomicLong();

    private boolean loop = true;

    public void put(long minVal, long maxVal, long interval) {
        log.info("startVal:{},endVal:{},interval:{}", minVal, maxVal, interval);
        minVal = maxMinVal(minVal);
        cancel();
        int tm;
        long avgVal = Math.max(maxVal - minVal, 0);
        result.set(minVal);
        if (avgVal == 0 || (tm = (int) (interval / avgVal)) <= 0) {
            return;
        }
        loop = true;
        schedule = taskScheduler.schedule(() -> {
            if (!loop) {
                return;
            }
            long addedAndGet = result.addAndGet(1);
            loop = addedAndGet != maxVal;
            log.info("自动增长后：{}", addedAndGet);
        }, triggerContext -> {
            Date time = triggerContext.lastActualExecutionTime();
            if (Objects.isNull(time)) {
                time = DateUtil.date();
            }
            return DateUtil.offsetSecond(time, tm);
        });

        log.info("自动增长开启成功,周期：{}秒", tm);
    }

    public Long get() {

        return result.get();
    }

    private synchronized void cancel() {
        if (Objects.isNull(schedule)) {
            return;
        }
        if (!schedule.isCancelled()) {
            schedule.cancel(true);
        }
    }

    private long maxMinVal(long minVal) {
        String cacheKey = "cache_" + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_PATTERN);
        long result = Math.max(cacheMap.getOrDefault(cacheKey, 0L), minVal);
        cacheMap.clear();
        cacheMap.put(cacheKey, result);
        return result;
    }
}
